package org.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.example.entity.CustomerInfo;
import org.example.entity.CustomerOrder;
import org.example.entity.CustomerRepayPlan;
import org.example.mapper.CustomerInfoMapper;
import org.example.mapper.CustomerOrderMapper;
import org.example.mapper.CustomerRepayPlanMapper;
import org.example.service.HaohanLoanDataCleanupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 浩瀚小贷数据清理服务实现
 * 用于按月份平均删除浩瀚小贷未结清数据，保持剩余金额不超过六亿
 */
@Slf4j
@Service
public class HaohanLoanDataCleanupServiceImpl implements HaohanLoanDataCleanupService {
    
    private static final String HAOHAN_PRODUCT_NAME = "浩瀚小贷";
    private static final String UNPAID_STATUS = "未结清";
    
    @Autowired
    private CustomerOrderMapper customerOrderMapper;
    
    @Autowired
    private CustomerInfoMapper customerInfoMapper;
    
    @Autowired
    private CustomerRepayPlanMapper customerRepayPlanMapper;
    
    @Override
    public BigDecimal getTotalRemainAmount() {
        QueryWrapper<CustomerOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_name", HAOHAN_PRODUCT_NAME)
                   .eq("status", UNPAID_STATUS);
        
        List<CustomerOrder> orders = customerOrderMapper.selectList(queryWrapper);
        
        return orders.stream()
                .map(CustomerOrder::getRemainPayAmount)
                .filter(Objects::nonNull)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }
    
    @Override
    public List<MonthlyOrderStats> getMonthlyOrderStats() {
        QueryWrapper<CustomerOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("product_name", HAOHAN_PRODUCT_NAME)
                   .eq("status", UNPAID_STATUS)
                   .orderByAsc("fr_time");
        
        List<CustomerOrder> orders = customerOrderMapper.selectList(queryWrapper);
        
        // 按月份分组统计
        Map<String, List<CustomerOrder>> monthlyOrders = orders.stream()
                .collect(Collectors.groupingBy(order -> {
                    String frTime = order.getFrTime();
                    if (frTime != null && frTime.length() >= 7) {
                        return frTime.substring(0, 7); // 提取yyyy-MM格式
                    }
                    return "unknown";
                }));
        
        List<MonthlyOrderStats> statsList = new ArrayList<>();
        
        for (Map.Entry<String, List<CustomerOrder>> entry : monthlyOrders.entrySet()) {
            String month = entry.getKey();
            List<CustomerOrder> monthOrders = entry.getValue();
            
            int totalCount = monthOrders.size();
            BigDecimal totalRemainAmount = monthOrders.stream()
                    .map(CustomerOrder::getRemainPayAmount)
                    .filter(Objects::nonNull)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            
            List<String> orderNos = monthOrders.stream()
                    .map(CustomerOrder::getOrderNo)
                    .collect(Collectors.toList());
            
            statsList.add(new MonthlyOrderStats(month, totalCount, totalRemainAmount, orderNos));
        }
        
        return statsList;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CleanupResult executeCleanup(BigDecimal targetRemainAmount) {
        log.info("开始执行浩瀚小贷数据清理，目标剩余金额: {}", targetRemainAmount);
        
        try {
            // 获取当前总剩余金额
            BigDecimal currentTotalAmount = getTotalRemainAmount();
            log.info("当前浩瀚小贷未结清订单总剩余金额: {}", currentTotalAmount);
            
            // 如果当前金额已经小于等于目标金额，无需删除
            if (currentTotalAmount.compareTo(targetRemainAmount) <= 0) {
                log.info("当前剩余金额 {} 已小于等于目标金额 {}，无需删除数据", currentTotalAmount, targetRemainAmount);
                return new CleanupResult(true, "当前剩余金额已满足要求，无需删除数据");
            }
            
            // 计算需要删除的金额
            BigDecimal amountToDelete = currentTotalAmount.subtract(targetRemainAmount);
            log.info("需要删除的金额: {}", amountToDelete);
            
            // 获取月度统计信息
            List<MonthlyOrderStats> monthlyStats = getMonthlyOrderStats();
            log.info("获取到 {} 个月份的数据", monthlyStats.size());
            
            // 计算每个月份需要删除的比例
            BigDecimal totalAmount = monthlyStats.stream()
                    .map(MonthlyOrderStats::getTotalRemainAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            
            CleanupResult result = new CleanupResult(true, "数据清理完成");
            result.setOriginalAmount(currentTotalAmount);
            result.setFinalAmount(targetRemainAmount);
            
            int totalDeletedOrders = 0;
            int totalDeletedCustomers = 0;
            int totalDeletedRepayPlans = 0;
            
            // 按月份平均删除
            for (MonthlyOrderStats stats : monthlyStats) {
                // 计算该月份需要删除的金额
                BigDecimal monthRatio = stats.getTotalRemainAmount().divide(totalAmount, 6, RoundingMode.HALF_UP);
                BigDecimal monthAmountToDelete = amountToDelete.multiply(monthRatio);
                
                // 计算该月份需要删除的订单数量
                int monthDeleteCount = calculateDeleteCount(stats.getOrderNos(), monthAmountToDelete);
                
                if (monthDeleteCount > 0) {
                    log.info("月份 {} 需要删除 {} 个订单，金额约 {}", stats.getMonth(), monthDeleteCount, monthAmountToDelete);
                    
                    DeleteResult deleteResult = deleteOrdersByMonth(stats.getMonth(), monthDeleteCount);
                    if (deleteResult.isSuccess()) {
                        totalDeletedOrders += deleteResult.getDeletedOrders();
                        totalDeletedCustomers += deleteResult.getDeletedCustomers();
                        totalDeletedRepayPlans += deleteResult.getDeletedRepayPlans();
                    } else {
                        log.error("删除月份 {} 数据失败: {}", stats.getMonth(), deleteResult.getMessage());
                    }
                }
            }
            
            result.setTotalDeletedOrders(totalDeletedOrders);
            result.setTotalDeletedCustomers(totalDeletedCustomers);
            result.setTotalDeletedRepayPlans(totalDeletedRepayPlans);
            
            // 验证最终结果
            BigDecimal finalAmount = getTotalRemainAmount();
            result.setFinalAmount(finalAmount);
            
            log.info("数据清理完成，删除了 {} 个订单，{} 个客户信息，{} 个还款计划", 
                    totalDeletedOrders, totalDeletedCustomers, totalDeletedRepayPlans);
            log.info("最终剩余金额: {}", finalAmount);
            
            return result;
            
        } catch (Exception e) {
            log.error("执行数据清理时发生异常", e);
            return new CleanupResult(false, "数据清理失败: " + e.getMessage());
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public DeleteResult deleteOrdersByMonth(String month, int deleteCount) {
        log.info("开始删除月份 {} 的 {} 个订单", month, deleteCount);
        
        try {
            // 查询该月份的订单
            QueryWrapper<CustomerOrder> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("product_name", HAOHAN_PRODUCT_NAME)
                       .eq("status", UNPAID_STATUS)
                       .likeRight("fr_time", month)
                       .orderByAsc("id")
                       .last("LIMIT " + deleteCount);
            
            List<CustomerOrder> ordersToDelete = customerOrderMapper.selectList(queryWrapper);
            
            if (ordersToDelete.isEmpty()) {
                log.warn("月份 {} 没有找到可删除的订单", month);
                return new DeleteResult(true, "没有找到可删除的订单");
            }
            
            int actualDeleteCount = ordersToDelete.size();
            BigDecimal deletedAmount = BigDecimal.ZERO;
            int deletedCustomers = 0;
            int deletedRepayPlans = 0;
            
            // 删除订单及相关数据
            for (CustomerOrder order : ordersToDelete) {
                try {
                    // 1. 删除还款计划
                    QueryWrapper<CustomerRepayPlan> repayPlanWrapper = new QueryWrapper<>();
                    repayPlanWrapper.eq("order_no", order.getOrderNo());
                    List<CustomerRepayPlan> repayPlans = customerRepayPlanMapper.selectList(repayPlanWrapper);
                    
                    for (CustomerRepayPlan repayPlan : repayPlans) {
                        customerRepayPlanMapper.deleteById(repayPlan.getId());
                        deletedRepayPlans++;
                    }
                    
                    // 2. 删除客户信息（如果该客户没有其他订单）
                    QueryWrapper<CustomerOrder> otherOrderWrapper = new QueryWrapper<>();
                    otherOrderWrapper.eq("pl_id_no", order.getPlIdNo())
                                    .ne("id", order.getId());
                    List<CustomerOrder> otherOrders = customerOrderMapper.selectList(otherOrderWrapper);
                    
                    if (otherOrders.isEmpty()) {
                        QueryWrapper<CustomerInfo> customerWrapper = new QueryWrapper<>();
                        customerWrapper.eq("pl_id_no", order.getPlIdNo());
                        List<CustomerInfo> customers = customerInfoMapper.selectList(customerWrapper);
                        
                        for (CustomerInfo customer : customers) {
                            customerInfoMapper.deleteById(customer.getId());
                            deletedCustomers++;
                        }
                    }
                    
                    // 3. 删除订单
                    customerOrderMapper.deleteById(order.getId());
                    
                    // 累计删除金额
                    if (order.getRemainPayAmount() != null) {
                        deletedAmount = deletedAmount.add(order.getRemainPayAmount());
                    }
                    
                } catch (Exception e) {
                    log.error("删除订单 {} 时发生异常: {}", order.getOrderNo(), e.getMessage(), e);
                }
            }
            
            log.info("成功删除月份 {} 的 {} 个订单，金额: {}", month, actualDeleteCount, deletedAmount);
            
            DeleteResult result = new DeleteResult(true, "删除成功");
            result.setDeletedOrders(actualDeleteCount);
            result.setDeletedCustomers(deletedCustomers);
            result.setDeletedRepayPlans(deletedRepayPlans);
            result.setDeletedAmount(deletedAmount);
            
            return result;
            
        } catch (Exception e) {
            log.error("删除月份 {} 数据时发生异常", month, e);
            return new DeleteResult(false, "删除失败: " + e.getMessage());
        }
    }
    
    /**
     * 计算需要删除的订单数量
     */
    private int calculateDeleteCount(List<String> orderNos, BigDecimal targetAmount) {
        if (orderNos.isEmpty() || targetAmount.compareTo(BigDecimal.ZERO) <= 0) {
            return 0;
        }
        
        // 查询这些订单的剩余金额
        QueryWrapper<CustomerOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("order_no", orderNos)
                   .eq("product_name", HAOHAN_PRODUCT_NAME)
                   .eq("status", UNPAID_STATUS)
                   .orderByAsc("remain_pay_amount"); // 从小到大排序，优先删除金额小的
        
        List<CustomerOrder> orders = customerOrderMapper.selectList(queryWrapper);
        
        BigDecimal currentAmount = BigDecimal.ZERO;
        int deleteCount = 0;
        
        for (CustomerOrder order : orders) {
            if (order.getRemainPayAmount() != null) {
                currentAmount = currentAmount.add(order.getRemainPayAmount());
                deleteCount++;
                
                if (currentAmount.compareTo(targetAmount) >= 0) {
                    break;
                }
            }
        }
        
        return deleteCount;
    }
}
